package org.lifxue.jqda.data;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.lifxue.jqda.data.bean.AppInfoBean;

/**
 * 
 * @Description:
 * @Author: zhangzuoqiang
 * @Date: Sep 26, 2011
 */
public class XmlData {

	private static Log logger = LogFactory.getLog(XmlData.class);
	private HashMap<String, List<AppInfoBean>> apps_app;// apps.xml中的apps内容
	private HashMap<String, List<String>> apps_dirs;// apps.xml中的dirs内容
	private HashMap<String, String> configs_config;// config.xml中的configs内容
	private HashMap<String, String> configs_hotkey;// config.xml中的hotkeys内容
	private List<String> INDEX_DIR;// 搜索扫描目录
	private List<String> INDEX_TYPE;// 搜索文件类型
	private String INDEX_CYCLE;// 搜索周期
	private String INDEX_LASTTIME;// 走后时间

	public XmlData() {
		apps_app = new HashMap<String, List<AppInfoBean>>();
		apps_dirs = new HashMap<String, List<String>>();
		configs_config = new HashMap<String, String>();
		configs_hotkey = new HashMap<String, String>();

		INDEX_DIR = new ArrayList<String>();
		INDEX_TYPE = new ArrayList<String>();
		INDEX_CYCLE = "每天一次";
		Date date = new Date();
		INDEX_LASTTIME = String.valueOf(date.getTime());// 当前时间（毫秒）
	}

	/**
	 * 读取apps.xml文件
	 * 
	 * @param file
	 */
	public void readAppsFile(File file) {
		SAXReader saxReader = new SAXReader(); // 使用SAXReader方式读取XML文件
		saxReader.setEncoding("UTF-8");
		// 加载数据库XML配置文件，得到Document对象
		Document document = null;
		try {
			document = saxReader.read(file);
		} catch (DocumentException ex) {
			logger.debug(ex);
		}
		Element root = document.getRootElement(); // 获得根节点
		readApps(root);
		readDirs(root);
	}

	/**
	 * 读取indexer.xml文件
	 * 
	 * @param file
	 */
	public void readIndexerFile(File file) {
		SAXReader saxReader = new SAXReader(); // 使用SAXReader方式读取XML文件
		saxReader.setEncoding("UTF-8");
		Document document = null;
		try {
			document = saxReader.read(file);
		} catch (DocumentException ex) {
			logger.debug(ex);
		}
		Element root = document.getRootElement(); // 获得根节点

		readIndexDir(root);
		readIndexType(root);
		readIndexCycle(root);
		readIndexLastTime(root);
	}

	/**
	 * 读取config.xml文件
	 * 
	 * @param file
	 */
	public void readConfigFile(File file) {
		SAXReader saxReader = new SAXReader(); // 使用SAXReader方式读取XML文件
		saxReader.setEncoding("UTF-8");
		// 加载数据库XML配置文件，得到Document对象
		Document document = null;
		try {
			document = saxReader.read(file);
		} catch (DocumentException ex) {
			logger.debug(ex);
		}
		Element root = document.getRootElement(); // 获得根节点

		readConfig(root);
		readHotKey(root);
	}

	/**
	 * 读取config.xml中的hotkey数据
	 * 
	 * @param root
	 */
	private void readHotKey(Element root) {
		Element hotkeys = root.element("hotkeys");
		if (hotkeys == null) {
			return;
		}
		List<Element> elements = hotkeys.elements(); // 得到table元素下的子元素集合
		if (elements == null) {
			return;
		}
		// 循环遍历集合中的每一个元素
		for (Element e : elements) {
			String key = e.attribute("key").getText();
			String text = e.getText();
			configs_hotkey.put(key, text);
		}
	}

	/**
	 * 读取要索引的目录
	 * 
	 * @param root
	 */
	private void readIndexDir(Element root) {
		Element dirs = root.element("dirs");
		if (dirs == null) {
			return;
		}
		List<Element> elements = dirs.elements();
		if (elements == null) {
			return;
		}
		// 循环遍历集合中的每一个元素
		for (Element e : elements) {
			getINDEX_DIR().add(e.getText());
		}
	}

	/**
	 * 读取要索引的文件类型
	 * 
	 * @param root
	 */
	private void readIndexType(Element root) {
		Element types = root.element("types");
		if (types == null) {
			return;
		}
		List<Element> elements = types.elements();
		if (elements == null) {
			return;
		}
		// 循环遍历集合中的每一个元素
		for (Element e : elements) {
			this.getINDEX_TYPE().add(e.getText());
		}
	}

	/**
	 * 读取要索引周期
	 * 
	 * @param root
	 */
	private void readIndexCycle(Element root) {
		Element cycle = root.element("cycle");
		if (cycle == null) {
			return;
		}
		this.setINDEX_CYCLE(cycle.getText());
	}

	/**
	 * 读取要lasttime
	 * 
	 * @param root
	 */
	private void readIndexLastTime(Element root) {
		Element lasttime = root.element("lasttime");
		if (lasttime == null) {
			this.setINDEX_LASTTIME("0");
			return;
		}
		this.setINDEX_LASTTIME(lasttime.getText());
	}

	/**
	 * 从config.xml中读取configs数据
	 * 
	 * @param root
	 */
	private void readConfig(Element root) {
		Element configs = root.element("configs");
		if (configs == null) {
			return;
		}
		List<Element> elements = configs.elements(); // 得到table元素下的子元素集合
		if (elements == null) {
			return;
		}
		// 循环遍历集合中的每一个元素
		for (Element e : elements) {
			String key = e.attribute("key").getText();
			String text = e.getText();
			configs_config.put(key, text);
		}
	}

	/**
	 * 从apps.xml文件中提取 dirs数据
	 * 
	 * @param root
	 */
	private void readDirs(Element root) {
		Element dirs = root.element("dirs");
		if (dirs == null) {
			return;
		}
		List<Element> elements = dirs.elements();
		if (elements == null) {
			return;
		}
		// 循环遍历集合中的每一个元素
		for (Element dir : elements) {
			List<String> list = new ArrayList<String>();
			String key = dir.attribute("key").getText();
			List<Element> exts = dir.elements();
			if (exts == null) {
				getApps_dirs().put(key, list);
				continue;
			}
			for (Element ext : exts) {
				list.add(ext.getText());
			}
			getApps_dirs().put(key, list);
		}

	}

	/**
	 * 从apps.xml中提取apps文件
	 * 
	 * @param root
	 */
	private void readApps(Element root) {
		Element apps = root.element("apps");
		if (apps == null) {
			return;
		}
		List<Element> elements = apps.elements(); // 得到apps元素下的子元素集合
		if (elements == null) {
			return;
		}
		// 循环遍历集合中的每一个元素
		for (Element e : elements) {
			List<AppInfoBean> list = new ArrayList<AppInfoBean>();
			String key = e.attribute("key").getText();
			List<Element> paths = e.elements();
			if (paths == null) {
				continue;
			}
			for (Element path : paths) {
				String volumeOfUse = path.attribute("volumeofuse").getText();
				AppInfoBean appinfo = new AppInfoBean();
				appinfo.setVolumeOfUse(Integer.parseInt(volumeOfUse));
				appinfo.setPath(path.getText());
				list.add(appinfo);
			}

			getApps_app().put(key, list);
		}

	}

	/**
	 * 创建xml文档
	 * 
	 * @param file
	 * @throws Exception
	 */
	public void createXml(File file) throws Exception {
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(file));
		// 产生 一个document对象
		Document doc = DocumentHelper.createDocument();
		// 添加一个根元素
		doc.addElement("root");
		xmlWriter.write(doc);
		xmlWriter.close();

	}

	/**
	 * 保存数据到索引配置文件
	 * 
	 * @param file
	 * @param dir
	 * @param type
	 * @param cycle
	 * @throws Exception
	 */
	public void writeIndexXml(File file, List<String> dirs, List<String> types,
			String cycle, String lasttime) throws Exception {
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(file));
		// 产生 一个document对象
		Document doc = DocumentHelper.createDocument();
		// 添加一个根元素
		Element root = doc.addElement("root");

		// 写入dir数据
		if (dirs != null && !dirs.isEmpty()) {// 非空
			Element oneElement = root.addElement("dirs");
			for (String dir : dirs) {
				Element twoElement = oneElement.addElement("dir");
				twoElement.setText(dir);
			}
		}

		// 写入type数据
		if (types != null && !types.isEmpty()) {// 非空
			Element oneElement = root.addElement("types");
			for (String type : types) {
				Element twoElement = oneElement.addElement("type");
				twoElement.setText(type);
			}
		}

		// 写入cycle数据
		if (cycle != null && !cycle.isEmpty()) {// 非空
			Element oneElement = root.addElement("cycle");
			oneElement.setText(cycle);
		}

		// 写入lasttime数据
		if (lasttime != null && !lasttime.isEmpty()) {// 非空
			Element oneElement = root.addElement("lasttime");
			oneElement.setText(lasttime);
		}

		xmlWriter.write(doc);
		xmlWriter.close();

	}

	public void writeConfigXml(File file, HashMap<String, String> config,
			HashMap<String, String> hotkey) throws Exception {
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(file));
		// 产生 一个document对象
		Document doc = DocumentHelper.createDocument();
		// 添加一个根元素
		Element root = doc.addElement("root");
		// 写入hotkey文件
		if (hotkey != null && !hotkey.isEmpty()) {// 非空
			Element oneElement = root.addElement("hotkeys");
			Iterator<?> i = hotkey.entrySet().iterator();
			while (i.hasNext()) {
				@SuppressWarnings("unchecked")
				Map.Entry<String, String> entry = (Map.Entry<String, String>) i
						.next();
				String key = (String) entry.getKey(); // 返回与此项对应的键
				String value = (String) entry.getValue(); // 返回与此项对应的值

				Element twoElement = oneElement.addElement("hotkey");
				twoElement.addAttribute("key", key);
				twoElement.setText(value);
			}
		}
		// 写入config文件
		if (config != null && !config.isEmpty()) {// 非空
			Element oneElement = root.addElement("configs");
			Iterator<?> i = config.entrySet().iterator();
			while (i.hasNext()) {
				@SuppressWarnings("unchecked")
				Map.Entry<String, String> entry = (Map.Entry<String, String>) i
						.next();
				String key = (String) entry.getKey(); // 返回与此项对应的键
				String value = (String) entry.getValue(); // 返回与此项对应的值

				Element twoElement = oneElement.addElement("config");
				twoElement.addAttribute("key", key);
				twoElement.setText(value);
			}
		}
		xmlWriter.write(doc);
		xmlWriter.close();

	}

	public void writeAppsXml(File file,
			HashMap<String, List<AppInfoBean>> apps,
			HashMap<String, List<String>> dir) throws Exception {
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(file));
		// 产生 一个document对象
		Document doc = DocumentHelper.createDocument();
		// 添加一个根元素
		Element root = doc.addElement("root");

		// 扫描目录
		if (dir != null && !dir.isEmpty()) {// 非空
			Element oneElement = root.addElement("dirs");
			Iterator<Entry<String, List<String>>> i = dir.entrySet().iterator();
			while (i.hasNext()) {
				Entry<String, List<String>> entry = (Entry<String, List<String>>) i
						.next();
				String key = (String) entry.getKey(); // 返回与此项对应的键
				List<String> list = (List<String>) entry.getValue(); // 返回与此项对应的值

				Element twoElement = oneElement.addElement("dir");
				twoElement.addAttribute("key", key);
				for (String value : list) {
					Element threeElement = twoElement.addElement("ext");
					threeElement.setText(value);
				}
			}
		}
		// 扫描到的数据
		if (apps != null && !apps.isEmpty()) {// 非空
			Element oneElement = root.addElement("apps");
			Iterator<Entry<String, List<AppInfoBean>>> i = apps.entrySet()
					.iterator();
			while (i.hasNext()) {
				Entry<String, List<AppInfoBean>> entry = (Entry<String, List<AppInfoBean>>) i
						.next();
				String key = (String) entry.getKey(); // 返回与此项对应的键
				List<AppInfoBean> list = (List<AppInfoBean>) entry.getValue(); // 返回与此项对应的值
				// logger.debug(key);
				Element twoElement = oneElement.addElement("app");
				twoElement.addAttribute("key", key);
				for (AppInfoBean value : list) {
					Element threeElement = twoElement.addElement("path");
					threeElement.addAttribute("volumeofuse",
							String.valueOf(value.getVolumeOfUse()));
					threeElement.setText(value.getPath());
					// logger.debug(value.getVolumeOfUse());
					// logger.debug(value.getPath());
				}
			}

		}
		xmlWriter.write(doc);
		xmlWriter.close();

	}

	public static void main(String[] args) throws Exception {
		// HashMap config = new HashMap();
		// config.put(String.valueOf(1), "测试a1-" + 1);
		// config.put(String.valueOf(2 + 1), "测试a1-" + 2);
		//
		// List<String> list = new ArrayList<String>();
		// list.add("*.exe");
		// list.add("*.bat");
		// HashMap dir = new HashMap();
		// dir.put("c:/", list);
		// dir.put("d:/", list);
		// new XmlData().writeAppsXml(new File("c:/b.xml"), config, dir);
		// new XmlData().writeConfigXml(new File("c:/c.xml"), config);
		//
		// new XmlData().readConfig(new File("c:/c.xml"));
		// new XmlData().readApps(new File("c:/b.xml"));
		// new XmlData().readDirs(new File("c:/b.xml"));
		// HashMap hm = new HashMap();
		// hm.put(String.valueOf(1), "测试a1-" + 1);
		// hm.put(String.valueOf(2 + 1), "测试a1-" + 2);
		//
		//
		// new ConfigXml().writerDocument(new File("c:/a.xml"), hm);
		//
		//
		// HashMap hm2 = new ConfigXml().readXml(new File("c:/a.xml"));
		//
		// Iterator i = hm2.entrySet().iterator();
		// while (i.hasNext()) {
		// java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
		// String key = (String) entry.getKey(); //返回与此项对应的键
		// String value = (String) entry.getValue(); //返回与此项对应的值
		//
		// System.out.println("key=" + key);
		// System.out.println("value=" + value);
		//
		// }
		//
	}

	/**
	 * @return the apps_app
	 */
	public HashMap<String, List<AppInfoBean>> getApps_app() {
		return apps_app;
	}

	/**
	 * @param apps_app
	 *            the apps_app to set
	 */
	public void setApps_app(HashMap<String, List<AppInfoBean>> apps_app) {
		this.apps_app = apps_app;
	}

	/**
	 * @return the apps_dirs
	 */
	public HashMap<String, List<String>> getApps_dirs() {
		return apps_dirs;
	}

	/**
	 * @param apps_dirs
	 *            the apps_dirs to set
	 */
	public void setApps_dirs(HashMap<String, List<String>> apps_dirs) {
		this.apps_dirs = apps_dirs;
	}

	/**
	 * @return the configs_config
	 */
	public HashMap<String, String> getConfigs_config() {
		return configs_config;
	}

	/**
	 * @param configs_config
	 *            the configs_config to set
	 */
	public void setConfigs_config(HashMap<String, String> configs_config) {
		this.configs_config = configs_config;
	}

	/**
	 * @return the configs_hotkey
	 */
	public HashMap<String, String> getConfigs_hotkey() {
		return configs_hotkey;
	}

	/**
	 * @param configs_hotkey
	 *            the configs_hotkey to set
	 */
	public void setConfigs_hotkey(HashMap<String, String> configs_hotkey) {
		this.configs_hotkey = configs_hotkey;
	}

	/**
	 * @return the INDEX_DIR
	 */
	public List<String> getINDEX_DIR() {
		return INDEX_DIR;
	}

	/**
	 * @param INDEX_DIR
	 *            the INDEX_DIR to set
	 */
	public void setINDEX_DIR(List<String> INDEX_DIR) {
		this.INDEX_DIR = INDEX_DIR;
	}

	/**
	 * @return the INDEX_TYPE
	 */
	public List<String> getINDEX_TYPE() {
		return INDEX_TYPE;
	}

	/**
	 * @param INDEX_TYPE
	 *            the INDEX_TYPE to set
	 */
	public void setINDEX_TYPE(List<String> INDEX_TYPE) {
		this.INDEX_TYPE = INDEX_TYPE;
	}

	/**
	 * @return the INDEX_CYCLE
	 */
	public String getINDEX_CYCLE() {
		return INDEX_CYCLE;
	}

	/**
	 * @param INDEX_CYCLE
	 *            the INDEX_CYCLE to set
	 */
	public void setINDEX_CYCLE(String INDEX_CYCLE) {
		this.INDEX_CYCLE = INDEX_CYCLE;
	}

	/**
	 * @return the INDEX_LASTTIME
	 */
	public String getINDEX_LASTTIME() {
		return INDEX_LASTTIME;
	}

	/**
	 * @param INDEX_LASTTIME
	 *            the INDEX_LASTTIME to set
	 */
	public void setINDEX_LASTTIME(String INDEX_LASTTIME) {
		this.INDEX_LASTTIME = INDEX_LASTTIME;
	}
}
